/*
 * Copyright 2006-2008 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/**
 * Copyright 2007 MartiniMix.net
 */
package net.martinimix.edesk.search;

import com.bluemartini.database.BMDatabaseManager;
import com.bluemartini.dna.BMException;
import com.bluemartini.dna.BusinessObject;
import com.bluemartini.dna.BusinessObjectArray;
import com.bluemartini.util.CISObjectUtil;
import com.endeca.navigation.ERec;
import com.endeca.navigation.ERecList;

/**
 * Provides product search via an Endeca navigation Engine. 
 * 
 * @author Scott Rossillo
 *
 */
public class SkuSearch extends EndecaRecordSearch {
	
	protected final String skuIdProperty;
	
	/**
	 * Constructs a new product search using the given Endeca
	 * host and port.
	 * 
	 * @param endecaHost the host or IP address of the Endeca Navigation Engine
	 * 
	 * @param endecaPort the port of the Endeca Navigation Engine on the 
	 * given <code>endecaHost</code>
	 * 
	 * @param skuIdProperty the Endeca record property that will return
	 * that record's <code>sku_id</code>
	 */
	public SkuSearch(String endecaHost, int endecaPort, String skuIdProperty) {
		super(endecaHost, endecaPort);
		this.skuIdProperty = skuIdProperty;
	}
	
	/**
	 * Returns an array of products matching the given search terms.
	 * 
	 * @param searchTerms the search terms from which matching products should be returned
	 * 
	 * @return a <code>BusinessObjectArray</code> containing products matching the
	 * given <code>searchTerms</code>
	 * 
	 * @throws BMException if an error occurs while querying Endeca or retrieving products
	 * from the Blue Martini database
	 */
	public BusinessObjectArray findSkus(String searchTerms) throws BMException {
		
		final BusinessObjectArray array = new BusinessObjectArray();
		final ERecList endecaRecordList = findRecords(searchTerms);
		
		if(endecaRecordList == null) {
			return array;
		}
		
		for(int i = 0; i < endecaRecordList.size(); i++) {
			
			ERec record = (ERec) endecaRecordList.get(i);
			BusinessObject product = getSku(record, skuIdProperty);
			
			if(product != null) {
				array.addElement(product);
			}
		}
		
		return array;
	}
	
	/**
	 * Returns the Blue Maritni SKU from the given Endeca record.
	 * 
	 * @param record the <code>ERec</code> containing the identifier for the
	 * product to be returned
	 * 
	 * @param property the <code>ERec</code> property containing the Blue Martini
	 * product id (<code>sku_id</code>)
	 * 
	 * @return a SKU <code>BusinessObject</code> containing the product
	 * identified by the given <code>record</code>
	 * 
	 * @throws BMException if an error occurs while determining the product
	 * version from Blue Martini
	 */
	private BusinessObject getSku(ERec record, String property) throws BMException {
		
		Long id = null;
		BusinessObject sku = null;
		
		BMDatabaseManager.pushCurrentDatabase("main");
		try {
			id = Long.valueOf( (String) record.getProperties().get(property));
			sku = CISObjectUtil.getObjectDetails("main", id, "SKU");
		} catch(NumberFormatException e) {
			throw new BMException("Invalid sku_id in Endeca property sku_id");
		} catch (BMException e) {
			throw new BMException("Error getting product " + id, e, null);
		} finally {
			BMDatabaseManager.popCurrentDatabaseQuiet("main");
		}
		
		return sku;
	}

}
